import * as commonService from '../services/CommonCRUD';
import * as datetime from '../utils/datetime'
import { message } from 'antd';
import * as common from '../utils/common'

export default {
    namespace: null,
    state: {
        list: [],
        total: null,
        page: 1,
        pageSize: 10,
        isEditChange: false,
        showEdit: false,
        showSeek: false,
        showImport: false,
        record: {},
        sortor: {},
        filters: {},
        seeks: [],
        optionDatas: {},
        keyName: "ID",
        permID: null,
        selectedRowKeys: [],
        visibleFilterName: null
    },
    reducers: {
        save(state, { payload: { data: list, total, page, pageSize, sorter, filters, selectedRowKeys, seeks } }) {
            if (!sorter) {
                sorter = {}
            }
            if (!filters) {
                filters = {}
            }
            if (!seeks) {
                seeks = []
            }
            const visibleFilterName = null
            return { ...state, list, total, page, pageSize, sorter, filters, selectedRowKeys, visibleFilterName, seeks };
        },
        saveOptions(state, { payload: { optionDatas } }) {
            const isEditChange = false;
            return { ...state, optionDatas, isEditChange };
        },
        setSelectedRowKeys(state, { payload: { selectedRowKeys } }) {
            return { ...state, selectedRowKeys };
        },
        updateRecord(state, { payload: { keys } }) {
            let record = { ...state.record, ...keys }
            return { ...state, record };
        },
        setRecord(state, { payload: { record } }) {
            return { ...state, record };
        },
        setKeyName(state, { payload: { keyName, permID } }) {
            return { ...state, keyName, permID };
        },
        setFilter(state, { payload: { colName, filter } }) {
            const filterVal = { [colName]: filter }
            const filters = { ...state.filters, ...filterVal }
            return { ...state, filters }
        },
        setVisibleFilterName(state, { payload: { visibleFilterName } }) {
            return { ...state, visibleFilterName };
        },
        openEdit(state, { payload: { key } }) {
            let record = {}
            let index = -1
            if (key) {
                const { list, keyName } = state
                for (let i = 0; i < list.length; i++) {
                    if (list[i][keyName] === key) {
                        index = i;
                        break;
                    }
                }
                record = list[index]
            }
            const showEdit = true;
            const editIndex = index;
            return { ...state, showEdit, editIndex, record };
        },
        hideEdit(state) {
            const showEdit = false;
            return { ...state, showEdit };
        },
        editChange(state) {
            const isEditChange = true;
            return { ...state, isEditChange };
        },
        //清除页面缓存
        clearList(state, { payload: { list } }) {
            return { ...state, list };
        },
    },
    effects: {
        *fetch({ payload: { daoName, page, pageSize, sorter, filters, seeks, colName, filter } }, { select, call, put }) {
            try {   
                const m = yield select(state => state[daoName]);
                filters = filters === undefined ? m.filters : filters;
                seeks = seeks === undefined ? m.seeks : seeks;
                page = page === undefined ? m.page : page;
                pageSize = pageSize === undefined ? m.pageSize : pageSize;
                sorter = sorter === undefined ? m.sorter : sorter;
                if (colName !== undefined && filter !== undefined) {
                    const filterVal = { [colName]: filter }
                    let newFilters = { ...filters, ...filterVal }
                    if (filter === null) {
                        delete newFilters[colName]
                    }
                    filters = newFilters
                }
                let whereCauses = common.filtersTowhereCauses(filters)
                whereCauses = [...whereCauses, ...seeks]
                const orderItems = common.sorterToOrderItems(sorter)
                const listData = yield call(commonService.fetch, { daoName, page, pageSize, sorter: orderItems, filters: whereCauses, permID: m.permID });
                const selectedRowKeys = []
                if (listData) {
                    yield put({
                        type: 'save',
                        payload: {
                            data: listData.Objectlist,
                            total: listData.Count,
                            page: parseInt(page, 10),
                            pageSize: parseInt(pageSize, 10),
                            sorter, filters, selectedRowKeys,
                            seeks
                        },
                    });
                }
            } catch (e) {
                // console.log(e)
            }
        },
        *fetchOptions({ payload: { options } }, { call, put }) {
            let optionDatas = {}
            for (let i = 0; i < options.length; i++) {
                const o = options[i];
                const data = yield call(commonService.fetchOption, { daoName: o.daoName,where: o.where });
                if (data) {
                    let pData = {}
                    data.map((l, i) => {
                        let pNode = l[o.parentTpl]
                        if (!pNode) {
                            pNode = "top-node"
                        }
                        if (!pData[pNode]) {
                            pData[pNode] = []
                        }
                        pData[pNode].push(i)
                    })
                    let cascaderKeys = {}
                    const createTreeData = (t, p, keys) => {
                        if (!pData[p]) {
                            return
                        }
                        pData[p].map(i => {
                            const id = data[i][o.valueTpl];
                            const strId = '' + id;
                            const node = { value: strId, label: data[i][o.optionTpl], key: id }
                            let thisKeys = []
                            if (keys) {
                                thisKeys = keys.concat();
                            }
                            thisKeys.push(strId);
                            if (pData[id]) {
                                node.children = []
                                createTreeData(node.children, id, thisKeys)
                            }
                            cascaderKeys[id] = thisKeys
                            t.push(node)
                        })
                        return t;
                    }
                    let treeData = createTreeData([], "top-node");
                    optionDatas[o.daoName] = treeData;
                    if (o.isCascader) {
                        optionDatas[o.daoName + "_cascader"] = cascaderKeys;
                    }
                }
            }
            yield put({    
                type: 'saveOptions',
                payload: { optionDatas }
            });
        },
        *remove({ payload: { daoName, keys } }, { select, call, put }) {
            if (keys.length === 0) {
                return
            }
            if (keys.length > 1) {
                yield call(commonService.removeKeys, { daoName, keys });
            } else {
                const m = yield select(state => state[daoName]);
                let values = null
                for (let i = 0; i < m.list.length; i++) {
                    if (keys[0] === m.list[i][m.keyName]) {
                        values = m.list[i]
                        break
                    }
                }
                yield call(commonService.removeEntity, { daoName, values });
            }
            yield put({ type: 'reload', payload: { daoName } });
        },
        *patch({ payload: { daoName, values } }, { call, put }) {
            yield call(commonService.patch, { daoName, values });
            message.success("数据修改成功！", 3)
        },
        *create({ payload: { daoName, values } }, { call, put }) {
            const keys = yield call(commonService.create, { daoName, values });
            yield put({
                type: 'updateRecord',
                payload: { keys }
            });
            message.success("数据添加成功！", 3)
        },
        *clearFilter({ payload: { daoName } }, { put, select }) {
            const { page, sorter, pageSize } = yield select(state => state[daoName]);
            yield put({ type: 'fetch', payload: { daoName, page, pageSize, sorter, filters: {} } });
            message.success("过滤条件清除成功！", 3)
        },
        *reload({ payload: { daoName } }, { put, select }) {
            const { page, sorter, pageSize, filters, record } = yield select(state => state[daoName]);
            yield put({ type: 'fetch', payload: { daoName, page, pageSize, sorter, filters } });
        },
        *reloadWithFilters({ payload: { daoName, colName, filter } }, { put, select }) {
            const { page, sorter, pageSize, filters, record } = yield select(state => state[daoName]);
            const filterVal = { [colName]: filter }
            let newFilters = { ...filters, ...filterVal }
            if (!filter) {
                delete newFilters[colName]
            }
            yield put({ type: 'fetch', payload: { daoName, page, pageSize, sorter, filters: newFilters } });
        },
    },
};
